from flask import current_app, Blueprint, request
from flask_json import as_json
from flask_jwt_extended import jwt_required, get_jwt_identity

from app import db
from app.admin.is_staff_user import is_staff_user

from app.models import CommonResult, AuthPermission, BlogUser, AuthUserPermission
from . import service
from .auth_decorator import has_role
from app.common.enums import RoleCodeEnum

log = current_app.logger
user_permission = Blueprint('auth_user_permission', __name__, url_prefix='/auth/user_permission')


# 注册蓝图
def register_controller(app):
    app.register_blueprint(user_permission)


# 用户权限分配：直接关联权限
@user_permission.post('/distribution/<int:user_id>')
@jwt_required()
@has_role({RoleCodeEnum.ADMIN})
@is_staff_user
@as_json
def distribution_permission(user_id):
    data = request.get_json()
    # 查询到分配权限的用户
    record = BlogUser.query.get(user_id)
    if record is None:
        return CommonResult(code=500, msg='用户不存在')
    # 读取传入的权限id
    pids: list[int] = data.get('p_ids')
    # 如果传入的权限记录为空，就删除用户的全部权限记录
    if pids is None or len(pids) <= 0:
        db.session.query(AuthUserPermission).filter_by(user_id=user_id).delete()
        db.session.commit()
        return CommonResult(msg='设置成功')
    # 如果存在记录，获取已存在的权限列表，然后进行对比
    # 该添加的添加，该删除的删除
    exist_user_list = AuthUserPermission.query.filter(AuthUserPermission.user_id == record.id).all()
    if exist_user_list is not None and len(exist_user_list) > 0:
        exist_permission_ids: list[int] = [role_permission.permission_id for role_permission in exist_user_list]
        # 新增=存在 差 并集
        # 删除=修改 差 并集
        union: set = set(pids).union(set(exist_permission_ids))
        need_insert: set = union.difference(set(exist_permission_ids))
        need_delete: set = union.difference(set(pids))
        log.debug("用户设置权限，已存在=%s，修改=%s，并集=%s，新增=%s，删除=%s",
                  exist_permission_ids, pids, union, need_insert, need_delete)
        if len(need_insert) > 0:
            for pid in need_insert:
                if AuthPermission.query.get(pid):
                    save_data = AuthUserPermission(user_id=record.id, permission_id=pid)
                    db.session.add(save_data)
        if len(need_delete) > 0:
            for pid in need_delete:
                db.session.query(AuthUserPermission).filter(
                    AuthUserPermission.user_id == record.id,
                    AuthUserPermission.permission_id == pid
                ).delete()
        # 提交修改
        db.session.commit()
    else:
        # 以前没有权限记录，现在选择了，直接和用户绑定关系
        for pid in pids:
            if AuthPermission.query.get(pid):
                save_data = AuthUserPermission(user_id=record.id, permission_id=pid)
                db.session.add(save_data)
        db.session.commit()
    return CommonResult(msg='设置成功')


# 查询用户直连权限数组
@user_permission.get('/arr/<int:user_id>')
@jwt_required()
@is_staff_user
@as_json
def user_permission_list(user_id):
    list_data = AuthUserPermission.query.filter_by(user_id=user_id)
    permission_ids: list = [record.permission_id for record in list_data]
    return CommonResult(data=set(permission_ids))


# 用户权限列表：角色权限+直连权限
@user_permission.get('/list/<int:user_id>')
@jwt_required()
@is_staff_user
@as_json
def user_permission_all(user_id):
    permission_list = service.user_permission_all(user_id)
    return CommonResult(data=permission_list)


# 用户权限代码数组
@user_permission.get('/code_arr/<int:user_id>')
@jwt_required()
@is_staff_user
@as_json
def user_permission_code_arr(user_id):
    record = BlogUser.query.get(user_id)
    if record is None:
        return CommonResult(code=500, msg='用户不存在')
    # 获取权限列表
    permission_list = service.user_permission_all(user_id)
    # 提取权限代码
    code_arr: list[str] = [record.p_code for record in permission_list]
    return CommonResult(data=code_arr, msg='获取成功')


# 登录用户权限代码数组
@user_permission.get('/current')
@jwt_required()
@is_staff_user
@as_json
def current_user_permission_code_arr():
    user_id = get_jwt_identity()
    return user_permission_code_arr(user_id)
